#include <QtTest>

#include <QList>

#include "../tests_common.h"

#include "bitwin/roles.h"


using namespace BitWin;


typedef QList<role_t> RolesList;
Q_DECLARE_METATYPE(RolesList)

Q_DECLARE_METATYPE(RolesSet)


namespace
{

RolesSet tryImplicit(RolesSet roles_set)
{
    return roles_set;
}

} // Anonymous namespace end


class TestRoles: public QObject
{
    Q_OBJECT

private slots:

    void testSet_data();
    void testSet();

    void testSetImplicit_data();
    void testSetImplicit();
};


void TestRoles::testSet_data()
{
    QTest::addColumn<RolesSet>("roles_set");
    QTest::addColumn<RolesList>("included_roles");
    QTest::addColumn<RolesList>("excluded_roles");

    QTest::newRow("empty")
        << RolesSet()
        << RolesList() << RolesList()
    ;
    QTest::newRow("dual")
        << (BitwiseDataRole | DecDataRole)
        << (RolesList() << BitwiseDataRole << DecDataRole)
        << (RolesList() << HexDataRole)
    ;
    QTest::newRow("dual#2")
        << (HexDataRole | DecDataRole)
        << (RolesList() << HexDataRole << DecDataRole)
        << (RolesList() << BitwiseDataRole)
    ;
    QTest::newRow("repeating")
        << (BitwiseDataRole | DecDataRole | DecDataRole)
        << (RolesList() << BitwiseDataRole << DecDataRole)
        << (RolesList() << HexDataRole)
    ;
    QTest::newRow("triple")
        << (BitwiseDataRole | DecDataRole | HexDataRole)
        << (RolesList() << BitwiseDataRole << HexDataRole << DecDataRole)
        << RolesList()
    ;
}

void TestRoles::testSet()
{
    QFETCH(RolesSet, roles_set);
    
    QFETCH(RolesList, included_roles);
    foreach (role_t role, included_roles)
        QVERIFY(roles_set & role);
    
    QFETCH(RolesList, excluded_roles);
    foreach(role_t role, excluded_roles)
        QVERIFY(!(roles_set & role));
}

void TestRoles::testSetImplicit_data()
{
    QTest::addColumn<role_t>("role");
    QTest::addColumn<RolesList>("excluded_roles");

    QTest::newRow("BitwiseDataRole")
        << BitwiseDataRole
        << (RolesList() << HexDataRole << DecDataRole)
    ;
    QTest::newRow("HexDataRole")
        << HexDataRole
        << (RolesList() << BitwiseDataRole << DecDataRole)
    ;
    QTest::newRow("DecDataRole")
        << DecDataRole
        << (RolesList() << BitwiseDataRole << HexDataRole)
    ;
}

void TestRoles::testSetImplicit()
{
    QFETCH(role_t, role);
    RolesSet roles_set = tryImplicit(role);
    
    QVERIFY(roles_set & role);
    
    QFETCH(RolesList, excluded_roles);
    foreach(role_t role, excluded_roles)
        QVERIFY(!(roles_set & role));
}


QTEST_MAIN(TestRoles)


#include "main.moc"
